package crypto

import (
	"fmt"
	"strings"
)

//KeyGenerator key generator
type KeyGenerator interface {
	//KeyGen 使用指定参数生成私钥.
	KeyGen() (k Key, err error)
}

//KeyPairGen 生成公私钥对
func KeyPairGen() (KeyPair, error) {
	return KeyPairGenWithOpts(options.AsymmetricAlgorithm)
}

//KeyPairGenWithOpts 指定算法生成公私钥对
func KeyPairGenWithOpts(algorithm string) (KeyPair, error) {
	alg := strings.ToUpper(algorithm)
	generator, existed := csp.KeyGenerators[alg]
	if existed {
		k, err := generator.KeyGen()
		if err != nil {
			return nil, err
		}
		if k.IsSymmetric() {
			return nil, fmt.Errorf("algorithm %s is not a asymmetric method", algorithm)
		}
		return k.(KeyPair), nil
	}
	return nil, fmt.Errorf("algorithm %s is not supportted", algorithm)
}

//KeyGen 使用默认算法生成对称秘钥
func KeyGen() (Key, error) {
	return KeyGenWithOpts(options.SymmetricAlgorithm)
}

//KeyGenWithOpts 使用默认算法生成对称秘钥
func KeyGenWithOpts(algorithm string) (Key, error) {
	alg := strings.ToUpper(algorithm)
	generator, existed := csp.KeyGenerators[alg]
	if existed {
		k, err := generator.KeyGen()
		if err != nil {
			return nil, err
		}
		if !k.IsSymmetric() {
			return nil, fmt.Errorf("the algorithm %s is not a asymmetric method", algorithm)
		}
		return k, nil
	}
	return nil, fmt.Errorf("the algorithm %s is not registered", algorithm)
}
